package ar.uba.fi.tonyvaliente;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.LinkedList;

import ar.uba.fi.tonyvaliente.commands.AddDocumentCommand;
import ar.uba.fi.tonyvaliente.commands.AddDocumentsCommand;
import ar.uba.fi.tonyvaliente.commands.Command;
import ar.uba.fi.tonyvaliente.commands.CommandResult;
import ar.uba.fi.tonyvaliente.commands.CreateIndexCommand;
import ar.uba.fi.tonyvaliente.commands.CreditsCommand;
import ar.uba.fi.tonyvaliente.commands.DumpCommand;
import ar.uba.fi.tonyvaliente.commands.QueryDocumentsCommand;
import ar.uba.fi.tonyvaliente.commands.ShowDocumentCommand;

public class Main {

	public static void main(String[] args) {
		if (args.length > 0 && args[0].equals("-test")) {
			test();
			return;
		}

		showProgramInfo();

		LinkedList<Command> commands = new LinkedList<Command>();
		commands.add(new CreateIndexCommand(args));
		commands.add(new AddDocumentsCommand(args));
		commands.add(new AddDocumentCommand(args));
		commands.add(new QueryDocumentsCommand(args));
		commands.add(new ShowDocumentCommand(args));
		commands.add(new DumpCommand(args));
		commands.add(new CreditsCommand(args));

		boolean recognized = false;

		for (Command command : commands) {
			CommandResult result = command.execute();
			if (!result.isRecognized())
				continue;
			recognized = true;

			println();
			println(result.getMessage());
			println();
			break;
		}

		if (!recognized)
			showUsage(commands);
	}

	private static void showProgramInfo() {
		println("Ultra Mini Basic Text Search Engine - Tony Valiente (c) 2008");
	}

	private static void showUsage(LinkedList<Command> commands) {
		String mainClassName = getMainClassName();

		println();
		printf_("Usage: java %s -command arguments", mainClassName);
		println();
		println();

		for (Command command : commands) {
			if (command.isShadow())
				continue;

			println("     " + command.getSignature());
			println();
			println("       " + command.getDescription());

			for (int i = 0; i < command.getExamples().length; i++) {
				if (i == 0)
					printf_("       Example: ");
				else
					printf_("                ");
				printf_("java %s " + command.getExamples()[i], mainClassName);
				println();
			}
			println();
			println();
		}
		println();
		println();
	}

	private static void println(String message) {
		System.out.println(message);
	}

	private static void println() {
		System.out.println("");
	}

	private static void print__() {
		System.out.print("");
	}

	private static void print__(String message) {
		System.out.print(message);
	}

	private static void printf_(String format, Object... args) {
		System.out.printf(format, args);
	}

	private static String getMainClassName() {
		Exception e = new Exception();
		StackTraceElement[] stackTrace = e.getStackTrace();
		return stackTrace[stackTrace.length - 1].getClassName();
	}

	private static void test() {
		// println("==========================================");
		// println("==========================================");
		// println("Test1: begins");
		// test1();
		// println("Test1: ends");

		// println("==========================================");
		// println("==========================================");
		// println("Test2: begins");
		// test2();
		// println("Test2: ends");

		// println("==========================================");
		// println("==========================================");
		// println("Test3: begins");
		// test3();
		// println("Test3: ends");

		// println("==========================================");
		// println("==========================================");
		// println("Test4: begins");
		// test4();
		// println("Test4: ends");

		println("==========================================");
		println("==========================================");
		println("Test5: begins");
		test5();
		println("Test5: ends");
	}

	private static void test1() {
		Command command;
		CommandResult result;
		String[] args;

		println("-- CreateIndex --");
		args = new String[] { "-createIndex", "8" };
		command = new CreateIndexCommand(args);
		result = command.execute();
		println(result.getMessage());

		PrintWriter writer;
		try {
			writer = new PrintWriter(new BufferedWriter(new FileWriter(
					"test.htm")));
		} catch (IOException e) {
			e.printStackTrace();
			return;
		}
		writer.println("<html><head></head><body>");
		writer.println("empresa comida empresa");
		writer.println("</body></html>");
		writer.close();

		args = new String[] { "-addDocument", "test.htm" };
		println("-- AddDocument --");
		command = new AddDocumentCommand(args);
		result = command.execute();
		println(result.getMessage());

		File file = new File("test.htm");
		file.delete();

		args = new String[] { "-query", "empresa" };
		println("-- QueryDocuments --");
		command = new QueryDocumentsCommand(args);
		result = command.execute();
		println(result.getMessage());

		QueryDocumentsCommand queryDocumentsCommand = (QueryDocumentsCommand) command;
		print__("Test1: 1 - ");
		if (queryDocumentsCommand.getDocumentIds().size() == 1)
			println("Bien");
		else
			println("Mal");

		print__("Test1: 2 - ");
		if (queryDocumentsCommand.getDocumentIds().get(0).equals(1))
			println("Bien");
		else
			println("Mal");
	}

	private static void test2() {
		Command command;
		CommandResult result;
		String[] args;

		println("-- CreateIndex --");
		args = new String[] { "-createIndex", "8" };
		command = new CreateIndexCommand(args);
		result = command.execute();
		println(result.getMessage());

		args = new String[] { "-addDocument",
				"tests/docs/Historia_de_la_electricidad.htm" };
		println("-- AddDocument --");
		command = new AddDocumentCommand(args);
		result = command.execute();
		println(result.getMessage());

		args = new String[] { "-query", "planeta" };
		println("-- QueryDocuments --");
		command = new QueryDocumentsCommand(args);
		result = command.execute();
		println(result.getMessage());

		QueryDocumentsCommand queryDocumentsCommand = (QueryDocumentsCommand) command;
		LinkedList<Integer> documents = queryDocumentsCommand.getDocumentIds();
		print__("Test2: 1 - ");
		if (documents.size() != 0)
			println("Mal");
		else
			println("Bien");
	}

	private static void test3() {
		Command command;
		CommandResult result;
		String[] args;

		println("-- CreateIndex --");
		args = new String[] { "-createIndex", "12" };
		command = new CreateIndexCommand(args);
		result = command.execute();
		println(result.getMessage());

		args = new String[] { "-addDocuments", "tests/docs", "H*.htm" };
		println("-- AddDocuments --");
		command = new AddDocumentsCommand(args);
		result = command.execute();
		println(result.getMessage());

		args = new String[] { "-query", "planeta" };
		println("-- QueryDocuments --");
		command = new QueryDocumentsCommand(args);
		result = command.execute();
		println(result.getMessage());

		QueryDocumentsCommand queryDocumentsCommand = (QueryDocumentsCommand) command;
		print__("Test3: 1 - ");
		if (queryDocumentsCommand.getDocumentIds().size() == 0)
			println("Bien");
		else
			println("Mal");

		args = new String[] { "-query", "geografia" };
		println("-- QueryDocuments --");
		command = new QueryDocumentsCommand(args);
		result = command.execute();
		println(result.getMessage());

		queryDocumentsCommand = (QueryDocumentsCommand) command;
		print__("Test3: 2 - ");
		if (queryDocumentsCommand.getDocumentIds().size() == 1)
			println("Bien");
		else
			println("Mal");
	}

	private static void test4() {
		Command command;
		CommandResult result;
		String[] args;

		println("-- CreateIndex --");
		args = new String[] { "-createIndex", "6" };
		command = new CreateIndexCommand(args);
		result = command.execute();
		println(result.getMessage());

		args = new String[] { "-addDocument",
				"tests/docs/Edicto_de_Precios.htm" };
		println("-- AddDocument --");
		command = new AddDocumentCommand(args);
		result = command.execute();
		println(result.getMessage());

		args = new String[] { "-addDocument",
				"tests/docs/Historia_de_la_electricidad.htm" };
		println("-- AddDocument --");
		command = new AddDocumentCommand(args);
		result = command.execute();
		println(result.getMessage());

		args = new String[] { "-dump" };
		println("-- Dump --");
		command = new DumpCommand(args);
		result = command.execute();
		println(result.getMessage());
	}

	private static void test5() {
		Command command;
		CommandResult result;
		String[] args;

		println("-- CreateIndex --");
		args = new String[] { "-createIndex", "12" };
		command = new CreateIndexCommand(args);
		result = command.execute();
		println(result.getMessage());

		// args = new String[] { "-addDocuments", "tests/docs", /*"C*.htm",*/
		// "H*.htm"/*, "M*.htm", "A*.htm"*/ };
		// println("-- AddDocuments --");
		// command = new AddDocumentsCommand(args);
		args = new String[] { "-addDocument",
				"tests/docs/Historia_de_la_electricidad.htm" };
		println("-- AddDocument --");
		command = new AddDocumentCommand(args);
		result = command.execute();
		println(result.getMessage());

		args = new String[] { "-dump", "c:\\dump.txt" };
		println("-- Dump --");
		command = new DumpCommand(args);
		result = command.execute();
		println(result.getMessage());
	}
}
